// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:math' show pi;

import 'package:flutter/material.dart';

const int numRows = 26;
const int numCols = 39;

class DrawArcsPage extends StatefulWidget {
  const DrawArcsPage({super.key, required this.paintStyle});

  final PaintingStyle paintStyle;

  @override
  State<DrawArcsPage> createState() => _DrawArcsPageState();
}

class _DrawArcsPageState extends State<DrawArcsPage> with SingleTickerProviderStateMixin {
  late final AnimationController controller;
  double tick = 0.0;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(vsync: this, duration: const Duration(hours: 1));
    controller.addListener(() {
      setState(() {
        tick += 1;
      });
    });
    controller.forward(from: 0);
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.fromLTRB(numRows.toDouble(), 0, numRows * 2, numRows.toDouble()),
      child: CustomPaint(painter: ArcsPainter(tick, widget.paintStyle), child: Container()),
    );
  }
}

class ArcsPainter extends CustomPainter {
  ArcsPainter(this.tick, this.paintStyle);

  final double tick;
  final PaintingStyle paintStyle;

  static const List<Color> kColors = <Color>[
    Colors.red,
    Colors.blue,
    Colors.green,
    Colors.yellow,
    Colors.orange,
    Colors.purple,
    Colors.pink,
    Colors.deepPurple,
  ];

  @override
  void paint(Canvas canvas, Size size) {
    if (size.width == 0) {
      return;
    }
    canvas.drawPaint(Paint()..color = Colors.white);
    for (int row = 0; row < numRows; row++) {
      for (int col = 0; col < numCols; col++) {
        final Offset center = Offset((col / numCols) * size.width, (row / numRows) * size.height);
        // Radius increases with row.
        final double radius = row.toDouble();
        // Sweep angle repeatedly goes from -2pi to 2pi.
        final double sweepAngle = (tick / 20) % (4 * pi) - 2 * pi;
        // useCenter alternates with each row.
        final bool useCenter = (row % 2).isEven;
        // Stroke width is proportional to radius (row), and increases with column up to 2 * radius.
        final double strokeWidth = 2 * radius * (col / numCols);
        // Color changes with each arc.
        final Color color = kColors[(row * numCols + col) % kColors.length].withValues(alpha: 0.5);
        // Stroke cap changes with each row.
        final StrokeCap cap = StrokeCap.values[row % StrokeCap.values.length];
        canvas.drawArc(
          Rect.fromCircle(center: center, radius: radius),
          0,
          sweepAngle,
          useCenter,
          Paint()
            ..color = color
            ..style = paintStyle
            ..strokeWidth = strokeWidth
            ..strokeCap = cap,
        );
      }
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}
